﻿// Decompiled with JetBrains decompiler
// Type: UnityEngine.Windows.WebCam.PhotoCaptureFrame
// Assembly: UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E6AE6B5A-2752-4B07-9528-C8B77C62CE79
// Assembly location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll
// XML documentation location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.xml

using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using UnityEngine.Bindings;
using UnityEngine.Scripting.APIUpdating;

#nullable disable
namespace UnityEngine.Windows.WebCam
{
  /// <summary>
  ///   <para>Contains information captured from the web camera.</para>
  /// </summary>
  [NativeHeader("PlatformDependent/Win/Webcam/PhotoCaptureFrame.h")]
  [NativeConditional("(PLATFORM_WIN || PLATFORM_WINRT) && !PLATFORM_XBOXONE")]
  [MovedFrom("UnityEngine.XR.WSA.WebCam")]
  public sealed class PhotoCaptureFrame : IDisposable
  {
    private IntPtr m_NativePtr;

    /// <summary>
    ///   <para>The length of the raw IMFMediaBuffer which contains the image captured.</para>
    /// </summary>
    public int dataLength { get; private set; }

    /// <summary>
    ///   <para>Specifies whether or not spatial data was captured.</para>
    /// </summary>
    public bool hasLocationData { get; private set; }

    /// <summary>
    ///   <para>The raw image data pixel format.</para>
    /// </summary>
    public CapturePixelFormat pixelFormat { get; private set; }

    [ThreadAndSerializationSafe]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern int GetDataLength();

    [ThreadAndSerializationSafe]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern bool GetHasLocationData();

    [ThreadAndSerializationSafe]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern CapturePixelFormat GetCapturePixelFormat();

    public bool TryGetCameraToWorldMatrix(out Matrix4x4 cameraToWorldMatrix)
    {
      cameraToWorldMatrix = Matrix4x4.identity;
      if (!this.hasLocationData)
        return false;
      cameraToWorldMatrix = this.GetCameraToWorldMatrix();
      return true;
    }

    [NativeConditional("PLATFORM_WIN && !PLATFORM_XBOXONE", "Matrix4x4f()")]
    [NativeName("GetCameraToWorld")]
    [ThreadAndSerializationSafe]
    private Matrix4x4 GetCameraToWorldMatrix()
    {
      Matrix4x4 ret;
      this.GetCameraToWorldMatrix_Injected(out ret);
      return ret;
    }

    public bool TryGetProjectionMatrix(out Matrix4x4 projectionMatrix)
    {
      if (this.hasLocationData)
      {
        projectionMatrix = this.GetProjection();
        return true;
      }
      projectionMatrix = Matrix4x4.identity;
      return false;
    }

    public bool TryGetProjectionMatrix(
      float nearClipPlane,
      float farClipPlane,
      out Matrix4x4 projectionMatrix)
    {
      if (this.hasLocationData)
      {
        float num1 = 0.01f;
        if ((double) nearClipPlane < (double) num1)
          nearClipPlane = num1;
        if ((double) farClipPlane < (double) nearClipPlane + (double) num1)
          farClipPlane = nearClipPlane + num1;
        projectionMatrix = this.GetProjection();
        float num2 = (float) (1.0 / ((double) farClipPlane - (double) nearClipPlane));
        float num3 = (float) -((double) farClipPlane + (double) nearClipPlane) * num2;
        float num4 = (float) -(2.0 * (double) farClipPlane * (double) nearClipPlane) * num2;
        projectionMatrix.m22 = num3;
        projectionMatrix.m23 = num4;
        return true;
      }
      projectionMatrix = Matrix4x4.identity;
      return false;
    }

    [NativeConditional("PLATFORM_WIN && !PLATFORM_XBOXONE", "Matrix4x4f()")]
    [ThreadAndSerializationSafe]
    private Matrix4x4 GetProjection()
    {
      Matrix4x4 ret;
      this.GetProjection_Injected(out ret);
      return ret;
    }

    /// <summary>
    ///   <para>This method will copy the captured image data into a user supplied texture for use in Unity.</para>
    /// </summary>
    /// <param name="targetTexture">The target texture that the captured image data will be copied to.</param>
    public void UploadImageDataToTexture(Texture2D targetTexture)
    {
      if ((UnityEngine.Object) targetTexture == (UnityEngine.Object) null)
        throw new ArgumentNullException(nameof (targetTexture));
      if (this.pixelFormat != 0)
        throw new ArgumentException("Uploading PhotoCaptureFrame to a texture is only supported with BGRA32 CameraFrameFormat!");
      this.UploadImageDataToTexture_Internal(targetTexture);
    }

    [NativeName("UploadImageDataToTexture")]
    [NativeConditional("(PLATFORM_WIN || PLATFORM_WINRT) && !PLATFORM_XBOXONE")]
    [ThreadAndSerializationSafe]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void UploadImageDataToTexture_Internal(Texture2D targetTexture);

    /// <summary>
    ///   <para>Provides a COM pointer to the native IMFMediaBuffer that contains the image data.</para>
    /// </summary>
    /// <returns>
    ///   <para>A native COM pointer to the IMFMediaBuffer which contains the image data.</para>
    /// </returns>
    [NativeConditional("(PLATFORM_WIN || PLATFORM_WINRT) && !PLATFORM_XBOXONE")]
    [ThreadAndSerializationSafe]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern IntPtr GetUnsafePointerToBuffer();

    public void CopyRawImageDataIntoBuffer(List<byte> byteBuffer)
    {
      if (byteBuffer == null)
        throw new ArgumentNullException(nameof (byteBuffer));
      byte[] numArray = new byte[this.dataLength];
      this.CopyRawImageDataIntoBuffer_Internal(numArray);
      if (byteBuffer.Capacity < numArray.Length)
        byteBuffer.Capacity = numArray.Length;
      byteBuffer.Clear();
      byteBuffer.AddRange((IEnumerable<byte>) numArray);
    }

    [NativeName("CopyRawImageDataIntoBuffer")]
    [ThreadAndSerializationSafe]
    [NativeConditional("(PLATFORM_WIN || PLATFORM_WINRT) && !PLATFORM_XBOXONE")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    internal extern void CopyRawImageDataIntoBuffer_Internal([Out] byte[] byteArray);

    internal PhotoCaptureFrame(IntPtr nativePtr)
    {
      this.m_NativePtr = nativePtr;
      this.dataLength = this.GetDataLength();
      this.hasLocationData = this.GetHasLocationData();
      this.pixelFormat = this.GetCapturePixelFormat();
      GC.AddMemoryPressure((long) this.dataLength);
    }

    private void Cleanup()
    {
      if (!(this.m_NativePtr != IntPtr.Zero))
        return;
      GC.RemoveMemoryPressure((long) this.dataLength);
      this.Dispose_Internal();
      this.m_NativePtr = IntPtr.Zero;
    }

    [NativeConditional("(PLATFORM_WIN || PLATFORM_WINRT) && !PLATFORM_XBOXONE")]
    [NativeName("Dispose")]
    [ThreadAndSerializationSafe]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void Dispose_Internal();

    /// <summary>
    ///   <para>Disposes the PhotoCaptureFrame and any resources it uses.</para>
    /// </summary>
    public void Dispose()
    {
      this.Cleanup();
      GC.SuppressFinalize((object) this);
    }

    ~PhotoCaptureFrame() => this.Cleanup();

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetCameraToWorldMatrix_Injected(out Matrix4x4 ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetProjection_Injected(out Matrix4x4 ret);
  }
}
